package ai.lazero.lazero;

import android.app.NotificationManager;
import android.content.Context;
//import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
//import android.os.PowerManager;
import android.support.annotation.NonNull;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.concurrent.TimeUnit;

import androidx.work.Worker;
//import androidx.work.ListenableWorker;
import androidx.work.WorkerParameters;
import im.delight.android.webview.AdvancedWebView;

public class WorkWeb extends Worker {
    public static WorkWeb instance;
    ////    }
    public Handler handler = new Handler();
//    public PowerManager.WakeLock mWakeLock = null;
    private Context mContext;
    public void antivirus(){
//        handler.removeCallbacks(task);
        // what is this task?
        handler.removeCallbacksAndMessages(null);
//        Intent intentSelf = new Intent(mContext,WorkWeb.class);
////        startService(intentSelf);
//        startWork(intentSelf);
    }
    //    public void viewSource(){};
//    public void takeWebviewScreenshot(){};
    public final String TAG = "WebWorker";
    public WorkWeb.ServiceHandler mServiceHandler;
    public StringBuilder inject_js_final = new StringBuilder();

    public Thread heartThread;
//    private NotificationManager notificationManager;

    public WorkWeb(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
        mContext = context;
        // add broadcast receiver to that thing. and do not use this shit. i mean do not use this thing.
//        notificationManager = (NotificationManager)
//                context.getSystemService(NOTIFICATION_SERVICE);
        // you are forcing me to build flutter apps. this sucks.
    }
    public AdvancedWebView webview;
    public final class ServiceHandler extends Handler {
        public int currentStartId;
        public boolean webviewScreenshotTaken = false;
        public boolean websiteIconTaken = false;

        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            webview = new AdvancedWebView(mContext);
            Log.i(TAG, "Creating WebView");
            //without this toast message, screenshot will be blank, dont ask me why...
            Toast.makeText(mContext, "Webworker Save completed.", Toast.LENGTH_SHORT).show();
// only one instance. no multiple webview?
            // This is important, so that the webview will render and we don't get blank screenshot
            webview.setDrawingCacheEnabled(true);
            //width and height of your webview and the resulting screenshot
            int width = 1920;
            int height = 1080;
            webview.measure(width, height);
            webview.layout(0, 0, width, height);
            webview.getSettings().setJavaScriptEnabled(true);
// check for flutter code.
            webview.getSettings().setAllowFileAccessFromFileURLs(true);
            webview.getSettings().setAllowUniversalAccessFromFileURLs(true);
// now let's implement the websocket. evaluate the thing.
            // and the worker.
//            webview.loadUrl(intent.getStringExtra(Database.FILE_LOCATION));
            // replace the call man.
            String bing_url = "https://www.bing.com";
            webview.loadUrl(bing_url);
            // just pass it to the thing.
            Log.i(TAG, "Loading URL: " + bing_url);
            webview.setWebViewClient(new WorkWeb.ServiceHandler.MyWebViewClient() {
                @Override
                public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                    Log.w(TAG, "Recieved error from WebView, description: " + description + ", Failing url: " + failingUrl);
                    //without this method, your app may crash...
                }

                @Override
                public void onPageFinished(WebView view, String url) {
                    Log.i(TAG, "Page finished, getting thumbnail");
                    view.loadUrl("javascript:" + inject_js_final.toString());
                    // shall be running a ws client here.
                    viewSource();
                    // this could be changed.
//                    takeWebviewScreenshot(intent.getStringExtra(Database.THUMBNAIL));
                    takeWebviewScreenshot();
// just launch it by the way.
                }
            });
        }
        // do another message receiver.
        // disassemble the whole process.
        // not sending intent. receiving broadcast.

        public class MyWebViewClient extends WebViewClient {
            //            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.startsWith("source://")) {
                    try {
                        String html = URLDecoder.decode(url, "UTF-8").substring(9);
                        Log.i(TAG,"TRYING TO SAVE HTML.");
                        saveHTMLToFile(html);
                    } catch (UnsupportedEncodingException e) {
                        Log.e("example", "failed to decode source", e);
                    }
                    webview.getSettings().setJavaScriptEnabled(true);
                    // this is shit.
                    return true;
                }
                // For all other links, let the WebView do it's normal thing
                return false;
            }
        }
        // start a websocket server.
        public void viewSource() {
            if (webview!=null){
//        webview.getSettings().setJavaScriptEnabled(true);
                webview.loadUrl(
                        "javascript:this.document.location.href = 'source://' + encodeURI(document.documentElement.outerHTML);");
            }else{Log.i(TAG,"WEBVIEW NULL CANNOT DUMP");}
        }
        public void takeWebviewScreenshot() {
//            final String outputFileLocation
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        TimeUnit.MILLISECONDS.sleep(1000);  //allow webview to render, otherwise screenshot may be blank or partial
                    } catch (InterruptedException e) {
                        //should never happen
                        Log.e(TAG, "InterruptedException when taking webview screenshot ", e);
                    }
                    // no saving. just print the length instead. or send intent?
//                    saveBitmapToFile(webview.getDrawingCache(), new File(outputFileLocation));
                    saveBitmapToFile(webview.getDrawingCache());
                    webviewScreenshotTaken = true;
                    // already dead by then.
                    Log.i(TAG,"SCREENSHOT SAVED.");
                    // do not stop.
//                    stopService();
                }
            }).start();
        }
        public void saveHTMLToFile(String bitmap) {
            if (bitmap == null) {
                Log.i(TAG,"html is empty.");
                return;
            }
//            outputFile.getParentFile().mkdirs();
            try {
                File sdCard = Environment.getExternalStorageDirectory();
                File directory = new File (sdCard.getAbsolutePath() + "/lazero/flutter/html");
//                dir.mkdirs();
                if (!directory.exists()){
                    directory.mkdirs();
                }
//                Timestamp timestamp = TimeStamp(System.currentTimeMillis());
                // method reloaded.
                Long tsLong = System.currentTimeMillis()/1000;
                String ts = tsLong.toString();
                String filename = "bing_html-"+ts+".html";
//            File file = new File(directory, filename);
                // passing in a file object.
//            OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                PrintWriter out = new PrintWriter(directory+"/"+filename);
                out.print(bitmap);
//            out.
//            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                // no logcat here.
                // make directory?
                // /sdcard/lazero/flutter/web
////                bitmap.
//                ByteArrayOutputStream stream = new ByteArrayOutputStream();
//                bitmap.compress(Bitmap.CompressFormat.JPEG,80,stream);
//                byte[] byteArray = stream.toByteArray();
//                String length="BITMAP SIZE: "+String.valueOf(byteArray.length);
//                Log.i(TAG,length);
//                Log.i(TAG,"hello world");
//print()
                out.flush();
                out.close();
                Log.i(TAG, "saved html to file");
                // not at this step.
            } catch (Exception e) {
                Log.e(TAG, "IoException while saving html to file", e);
            }
//            Log.i(TAG, "Saved Bitmap to file: " + outputFile.getPath());
        }
        public void saveBitmapToFile(Bitmap bitmap) {
            if (bitmap == null) {
                Log.i(TAG,"bitmap is empty.");
                return;
            }
//            outputFile.getParentFile().mkdirs();
            try {
                File sdCard = Environment.getExternalStorageDirectory();
                File directory = new File (sdCard.getAbsolutePath() + "/lazero/flutter/web");
//                dir.mkdirs();
                if (!directory.exists()){
                    directory.mkdirs();
                }
//                Timestamp timestamp = TimeStamp(System.currentTimeMillis());
                // method reloaded.
                Long tsLong = System.currentTimeMillis()/1000;
                String ts = tsLong.toString();
                String filename = "bing_screenshot-"+ts+".png";
                File file = new File(directory, filename);
                // passing in a file object.
                OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                // no logcat here.
                // make directory?
                // /sdcard/lazero/flutter/web
////                bitmap.
//                ByteArrayOutputStream stream = new ByteArrayOutputStream();
//                bitmap.compress(Bitmap.CompressFormat.JPEG,80,stream);
//                byte[] byteArray = stream.toByteArray();
//                String length="BITMAP SIZE: "+String.valueOf(byteArray.length);
//                Log.i(TAG,length);
//                Log.i(TAG,"hello world");
//print()
                Log.i(TAG,"web screenshot saved");
                // do not do extra things. null pointers.
                out.flush();
                out.close();
            } catch (Exception e) {
                Log.e(TAG, "IoException while saving bitmap to file", e);
            }
//            Log.i(TAG, "Saved Bitmap to file: " + outputFile.getPath());
        }

        // do not start that service. make it into a work instead of service.
        public void stopService() {
            if (heartThread!=null){
                heartThread=null;
            }
            if (websiteIconTaken && webviewScreenshotTaken) {
                Log.i(TAG, "Service stopped, with startId " + currentStartId + " completed");
//                stopSelf(currentStartId);
                // not within service context.
            }
        }
    }
    // send to external things or simply save to sdcard. just generate a random number and make some folders.
    @Override
    public Result doWork() {
//        super.onCreate();
//        String progress = "Starting Download";
//        setForegroundAsync(createForegroundInfo(progress));
        // must use latest workmanager
        instance=this;
        instance.coreLogic();
        instance.init();
        return Result.success();
        // shall get main looper?
    }
    public void coreLogic(){
//        Notification notification = note();
//        startForeground(1759, notification);
        Log.v("WEBWORKER", "START_SUCCESS");
//        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
//        filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
//        filter.addAction("your_action_strings"); //further more
//        filter.addAction("your_action_strings"); //further more
//        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        heartThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try{
                        Thread.sleep(1000);}catch(Exception e){Log.e(TAG,"sleep falied");break;}
                    if (webview!=null){
                        Long tsLong = System.currentTimeMillis()/1000;
                        String ts = tsLong.toString();
                        Log.e(TAG,"WEBVIEW WORKER PRESENT "+ts);
                    }else{Log.e(TAG,"DEAD WEBVIEW WORKER");}
                }
            };}
        );
//        heartThread.run();
        // how can we leave it alone? run after free?
        heartThread.start();
        mServiceHandler = new WorkWeb.ServiceHandler(Looper.getMainLooper()); // working
    }
//    @Override
    public void init() {
        Log.i(TAG,"WEB QUEST RECEIVED");
        // obtain what?
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = 1337;
//        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

//
//    @Override
//    public void onDestroy(){
//        antivirus();
//        mServiceHandler.stopService();
////        if (mWakeLock.isHeld()) {
////            mWakeLock.release();
////        }
//        // gonna restart.
//    }

}
